// include header files
var crypto = require('crypto');
var message = require('../lib/message');
var database = require('../lib/database');
var fotoString = require('../lib/fotostring');
var fotoNumber = require('../lib/fotonumber');
var fotoImage = require('../lib/fotoimage');
var codeOperation = require('../lib/code');

// connect db
database.connectDataBase();

// api signup
exports.signUp = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databasError, collection) {
			if (databasError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.fullName || !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotoString.FULL_NAME_MESSAGE
							+ message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.email) {
					result = fotoString.EMAIL
							+ message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.password) {
					result = fotoString.PASSWORD
							+ message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"email" : param.email
			}, {
				"email" : fotoString.TRUE,
				"_id" : fotoString.FALSE
			}, function(findObjectError, cursor) {
				if (cursor) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_EMAIL_EXIST_ERROR;
					response.json({
						"code" : code,
						"result" : result
					});
					database.closeDatabase();
					return;
				} else {
					param.tokenKey = crypto.createHash(fotoString.MD5).update(
							new Date().getTime().toString()).digest(
							fotoString.HEX);
					collection.insert(param, {
						safe : true
					}, function(insertObjectError, insertObjectResult) {
						if (!insertObjectError) {
							code = codeOperation.OPERATION_SUCCESS;
							collection.findOne({
								"email" : param.email
							}, {
								"tokenKey" : fotoString.TRUE,
								"fullName" : fotoString.TRUE,
								"_id" : fotoString.FALSE
							}, function(findObjectError, findObjectResult) {
								if (findObjectResult) {
									result = fotoString.TOKEN_KEY
											+ fotoString.EQUAL_OPERATOR
											+ findObjectResult.tokenKey
											+ fotoString.SEMI_COLON
											+ fotoString.FULL_NAME
											+ fotoString.EQUAL_OPERATOR
											+ findObjectResult.fullName;
									response.json({
										"code" : code,
										"result" : result
									});
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({
			"code" : code,
			"result" : result
		});
		database.closeDatabase();
		return;
	}
}

// api upload avatar
exports.uploadAvatar = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));

		if (!param.tokenKey) {
			code = codeOperation.PARAMETER_ERROR;
			result = fotoString.TOKEN_KEY_MESSAGE
					+ message.MESSAGE_FIELD_NULL_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		if (!request.files.avatar.name) {
			code = codeOperation.PARAMETER_ERROR;
			result = message.MESSAGE_FILE_HAS_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			collection.findOne({
				"tokenKey" : param.tokenKey
			}, {
				"tokenKey" : fotoString.TRUE
			}, function(findObjectError, findObjectResult) {
				if (findObjectResult) {
					var savePath = fotoImage.uploadImage(request.files.avatar,
							findObjectResult._id, fotoNumber.AVATAR);
					collection.update({
						"tokenKey" : param.tokenKey
					}, {
						$set : {
							"avatar" : savePath
						}
					}, function(updateObjectError, updateObjectResult) {
						if (!updateObjectError) {
							collection.findOne({
								"tokenKey" : param.tokenKey
							}, {
								"avatar" : fotoString.TRUE
							}, function(error, cursor) {
								code = codeOperation.OPERATION_SUCCESS;
								result = fotoString.AVATAR
										+ fotoString.EQUAL_OPERATOR
										+ cursor.avatar;
								response.json({
									"code" : code,
									"result" : result
								});
								database.closeDatabase();
								return;
							});
						}
					});

				} else {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({
						"code" : code,
						"result" : result
					});
					database.closeDatabase();
					return;
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({
			"code" : code,
			"result" : result
		});
		database.closeDatabase();
		return;
	}
}

// api login
exports.login = function(request, response) {
	try {
		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		var result, code;
		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.email) {
					result = fotoString.EMAIL
							+ message.MESSAGE_FIELD_NULL_ERROR;

				} else if (!param.password) {
					result = fotoString.PASSWORD
							+ message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"email" : param.email,
				"password" : param.password
			}, {
				"email" : fotoString.TRUE,
				"_id" : fotoString.FALSE
			}, function(findObjectError, findObjectResult) {
				if (!findObjectResult) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_LOGIN_FAILED_ERROR;
					response.json({
						"code" : code,
						"result" : result
					});
					database.closeDatabase();
					return;
				} else {
					var tokenKey = crypto.createHash(fotoString.MD5).update(
							new Date().getTime().toString()).digest(
							fotoString.HEX);
					collection.update({
						"email" : param.email,
						"password" : param.password
					}, {
						$set : {
							"tokenKey" : tokenKey
						}
					}, function(updateObjectError, updateObjectResult) {
						if (!updateObjectError) {
							code = codeOperation.OPERATION_SUCCESS;
							collection.findOne({
								"email" : param.email,
								"password" : param.password
							}, {
								"fullName" : fotoString.TRUE,
								"tokenKey" : fotoString.TRUE,
								"avatar" : fotoString.TRUE,
								"_id" : fotoString.FALSE
							}, function(error, item) {
								if (item) {
									result = fotoString.TOKEN_KEY
											+ fotoString.EQUAL_OPERATOR
											+ item.tokenKey
											+ fotoString.SEMI_COLON
											+ fotoString.FULL_NAME
											+ fotoString.EQUAL_OPERATOR
											+ item.fullName
											+ fotoString.SEMI_COLON
											+ fotoString.AVATAR
											+ fotoString.EQUAL_OPERATOR
											+ item.avatar;
									response.json({
										"code" : code,
										"result" : result
									});
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({
			"code" : code,
			"result" : result
		});
		database.closeDatabase();
		return;
	}
}

// api logout
exports.logout = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey) {
				code = codeOperation.PARAMETER_ERROR;
				result = fotoString.TOKEN_KEY_MESSAGE
						+ message.MESSAGE_FIELD_NULL_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"tokenKey" : param.tokenKey
			}, {
				"tokenKey" : fotoString.TRUE,
				"_id" : fotoString.FALSE
			}, function(findObjectError, findObjectResult) {
				if (!findObjectResult) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({
						"code" : code,
						"result" : result
					});
					database.closeDatabase();
					return;
				} else {
					collection.update({
						"tokenKey" : param.tokenKey
					}, {
						$set : {
							"tokenKey" : fotoString.EMPTY_STRING
						}
					}, function(updateObjectError, updateObjectResult) {
						if (!updateObjectError) {
							code = codeOperation.OPERATION_SUCCESS;
							result = fotoString.EMPTY_STRING;
							response.json({
								"code" : code,
								"result" : result
							});
							database.closeDatabase();
							return;
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({
			"code" : code,
			"result" : result
		});
		database.closeDatabase();
		return;
	}
}

// api update profile
exports.updateProfile = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({
				"code" : code,
				"result" : result
			});
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));
		var currentEmail = fotoString.EMPTY_STRING;

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey || !param.email || !param.fullName
					|| !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotoString.FULL_NAME_MESSAGE
							+ message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.email) {
					result = fotoString.EMAIL
							+ message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.password) {
					result = fotoString.PASSWORD
							+ message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.tokenKey) {
					result = fotoString.TOKEN_KEY_MESSAGE
							+ message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({
					"code" : code,
					"result" : result
				});
				database.closeDatabase();
				return;
			}

			collection.findOne({
				"tokenKey" : param.tokenKey
			}, {
				"email" : fotoString.TRUE,
				"_id" : fotoString.FALSE
			}, function(findObjectError, findObjectResult) {
				if (!findObjectResult) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({
						"code" : code,
						"result" : result
					});
					database.closeDatabase();
					return;
				} else {
					currentEmail = findObjectResult.email;
					collection.findOne({
						"email" : param.email
					}, function(findObjectError, cursor) {
						if (cursor && cursor.email != currentEmail) {
							code = codeOperation.OPERATION_ERROR;
							result = message.MESSAGE_EMAIL_EXIST_ERROR;
							response.json({
								"code" : code,
								"result" : result
							});
							database.closeDatabase();
							return;
						} else {
							collection.update({
								"tokenKey" : param.tokenKey
							}, {
								$set : {
									"email" : param.email,
									"password" : param.password,
									"fullName" : param.fullName
								}
							}, function(updateObjectError, updateObjectResult) {
								if (!updateObjectError) {
									code = codeOperation.OPERATION_SUCCESS;
									result = fotoString.EMPTY_STRING;
									response.json({
										"code" : code,
										"result" : result
									});
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({
			"code" : code,
			"result" : result
		});
		database.closeDatabase();
		return;
	}
}
